#ifndef ScriptComponent__h
#define ScriptComponent__h


#include <QtScript>

#include "RoComponent.h"


Q_DECLARE_METATYPE(QDomDocument);
Q_DECLARE_METATYPE(RoErrorStanza);
Q_DECLARE_METATYPE(RoInfoStanza);
Q_DECLARE_METATYPE(RoIqStanza);
Q_DECLARE_METATYPE(RoStanza);
Q_DECLARE_METATYPE(RoStanzaId);


class ScriptComponent:
    public RoComponent
{
    Q_OBJECT

    Q_PROPERTY( int activeQueriesCount
                READ activeQueriesCount );

public:

    typedef RoComponent super;

    ScriptComponent(RoModule * module, const QString & scriptFileName);

    bool result;

    QString scriptFileName;

    int activeQueriesCount() const { return queriesWithParameters.count(); }

public slots:

    void runScript();

    /// @param[in]      component_method  имя_компонента "::" имя_метода
    /// @param[in,out]  params            {argument: QDomDocument, dataAcceptor: function, resultAcceptor: function}
    bool query(const QString & component_method, QScriptValue params);

    /// Список (ромашковых) методов компонента, включая сгенерированные скриптом.
    virtual RoMethodResult ro_query_interface(RoIqStanza request, QDomDocument *answer);

    /// Для вызова из сценария
    void quit() { emit scriptFinished(); }

private:

    QScriptEngine engine;

    QScriptValue qsSelf;

    QMap<RoQuery*, QScriptValue> queriesWithParameters;

    static QScriptValue DomDocumentFromScriptValue(QScriptContext * context, QScriptEngine * engine);

    /// Вызов некого ромашкового метода (кто-то вызывает нас).
    /// Мы попадаем сюда при вызове любого метода.
    /// @param[in] stanza  должна быть <iq type=request/>
    virtual void query_in_start(RoIqStanza stanza);

private slots:

    void receive_query_datum(QDomDocument datum);
    void receive_query_result(bool error, QDomDocument answer);

signals:

    void scriptFinished();

}; // class ScriptComponent


#endif // ScriptComponent__h
